import { Ref } from 'vue'
import {
  serializeSelection,
  deserializeSelection,
  getElementChecksum,
} from '@notjosh/rangy-serializer'
import { getSelection } from '@notjosh/rangy-core'
import { useAnnotationStore } from '@/stores/annotation'
import { DialogPlugin } from 'tdesign-vue-next'

const annotationStore = useAnnotationStore()

function useSerialization(frameRef: Ref<HTMLIFrameElement>) {
  const serializeToCurrentLabel = (clearHighlight: Function) => {
    if (checkText()) {
      const bookmark = getSelection(frameRef.value.contentWindow!).getBookmark(
        undefined
      )
      // 高亮引入额外的span标签会导致序列化不一致，因此需要先清除高亮
      clearHighlight()
      getSelection(frameRef.value.contentWindow!).moveToBookmark(bookmark)
      const serialization = serializeSelection(
        getSelection(frameRef.value.contentWindow!),
        false,
        frameRef.value.contentDocument!.documentElement
      )
      annotationStore.currentLabel.bookmark = bookmark
      annotationStore.currentLabel.location = serialization
    } else {
      annotationStore.currentLabel.content = ''
      annotationStore.currentLabel.tagId = ''
      annotationStore.currentLabel.remark = ''
    }
  }

  const deserializePersentLabel = () => {
    annotationStore.presentLabelList.forEach((l) => {
      try {
        const sel = deserializeSelection(
          l.location,
          frameRef.value.contentDocument!.documentElement
        )
        l.bookmark = sel.getBookmark(undefined)
      } catch (err) {
        l.serializeError = true
      }
    })
  }

  const checkText = () => {
    const MAGIC_CHECKSUM = 'a6575e17'
    if (
      getElementChecksum(document.getElementById('checksum-test')) !=
      MAGIC_CHECKSUM
    ) {
      DialogPlugin({
        header: '标注文本检查错误',
        body: '系统检测到您的标注文本结构发生变化，标注相关功能将会受到影响。请您检查是否在浏览器中开启了翻译、强制黑暗模式等可能修改HTML结构的插件，如有开启，请在关闭插件后刷新网页重试。如未能解决，请联系管理员。',
        width: '50%',
        footer: false,
        theme: 'danger',
      })
      return false
    }
    return true
  }

  return {
    serializeToCurrentLabel,
    deserializePersentLabel,
    checkText,
  }
}

export { useSerialization }
